﻿using Grain.Grain;
using Grain.Strategy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Orleans.Configuration;
using Orleans.Runtime.Placement;
using Orleans.Runtime;
using OrleansDemo.Grain;
using System.Net;
using Utils;

var config = ConfigUtil.GetConfiguration();

var primarySiloIp = config.GetValue<string>("PrimarySiloIp");
var primarySiloPort = config.GetValue<int>("PrimarySiloPort");
var siloIp = config.GetValue<string>("SiloIp");
var siloPort = config.GetValue<int>("SiloPort");
var gatewayPort = config.GetValue<int>("GatewayPort");
var serverId = config.GetValue<string>("ServerId");
var urls = config.GetValue<string>("urls");

HelloGrain.ServerId = serverId;
HelloGrain2.ServerId = serverId;

var builder = new HostBuilder()
    .UseOrleans(c =>
    {
        //c.UseLocalhostClustering(siloPort, gatewayPort, new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1111), "HelloWorldApp", "dev")
        c.UseDevelopmentClustering(options =>
        {
            options.PrimarySiloEndpoint = new IPEndPoint(IPAddress.Parse(primarySiloIp), primarySiloPort);
        })
        .Configure<ClusterOptions>(options =>
        {
            options.ClusterId = "dev";
            options.ServiceId = "HelloWorldApp";
        })
        .Configure<EndpointOptions>(options =>
        {
            options.SiloPort = siloPort;
            options.GatewayPort = gatewayPort;
            options.AdvertisedIPAddress = IPAddress.Parse(siloIp);
            options.SiloListeningEndpoint = new IPEndPoint(IPAddress.Any, siloPort);
            options.GatewayListeningEndpoint = new IPEndPoint(IPAddress.Any, gatewayPort);
        })
        .ConfigureServices(serviceCollection =>
        {
            serviceCollection.AddKeyedSingleton<PlacementStrategy, SamplePlacementStrategy>(nameof(SamplePlacementStrategy));
            serviceCollection.AddKeyedSingleton<IPlacementDirector, SamplePlacementStrategyFixedSiloDirector>(typeof(SamplePlacementStrategy));
            serviceCollection.AddScoped(typeof(IHello), typeof(HelloGrain));
            serviceCollection.AddScoped(typeof(IHello2), typeof(HelloGrain2));
            serviceCollection.AddScoped(typeof(ISiloCount), typeof(SiloCount));
        })
         .Configure<SiloMessagingOptions>(options =>
         {
             options.ResponseTimeout = TimeSpan.FromMinutes(5);
         })
        //.UseAdoNetClustering(option =>
        //{
        //    option.ConnectionString = "server=localhost;database=orleans_demo;user id=root;password=123456;character set=utf8mb4;";
        //    option.Invariant = "MySql.Data.MySqlClient";
        //})
        //.AddAdoNetGrainStorage("OrleansStorage", options =>
        //{
        //    options.ConnectionString = "server=localhost;database=orleans_demo;user id=root;password=123456;character set=utf8mb4;";
        //    options.Invariant = "MySql.Data.MySqlClient";
        //})
        .AddMemoryGrainStorage("OrleansStorage")
        .UseDashboard(options =>
        {
            options.Username = "admin";
            options.Password = "123456";
            options.Host = "*";
            options.Port = 5029;
            options.HostSelf = true;
            options.CounterUpdateIntervalMs = 1000;
        })
        .ConfigureLogging(logging =>
        {
            logging.AddConsole();
            logging.AddFilter((name, level) =>
            {
                if (level <= LogLevel.Information && name != null && name.Contains("Orleans"))
                {
                    return false;
                }
                return true;
            });
        });
    });

var host = builder.Build();
await host.StartAsync();

Console.ReadLine();
